package item;

import hibernateUtil.Playerinfo;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;





import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import platform.Platform;
import player.Player;



public class ItemUtil {

	private static final Logger log = LoggerFactory.getLogger(ItemUtil.class);

	public static Bags getBagsFromDB(byte[] bytes, Playerinfo owner) {
		ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
		DataInputStream dis = new DataInputStream(bais);
		Bags bags = null;
		try {
			int version = dis.readByte(); // version;
			int bagCount = dis.readByte();

			bags = new Bags(owner, bagCount);
			for (int i = 0; i < bagCount; i++) {
				int id = dis.readByte();
				Bag bag = getBagFromDB(dis, bags, id);
				bags.addBag(bag);
			}

		} catch (IOException e) {
			e.printStackTrace();
		}
		return bags;
	}

	public static Bag getBagFromDB(DataInputStream dis, Bags bags, int id) {
		Bag bag = null;
		try {
			int gridCount = dis.readShort();
			int addSize = gridCount - 50;
			bag = new Bag(bags, id, 50, addSize > 0 ? addSize : 0);
			for (int i = 0; i < gridCount; i++) {
				int itemCount = dis.readShort();
				BagGrid grid = bag.getGrid(i);
				GameItem item = null;
				if (itemCount > 0) {
					item = getGameItemFromDB(dis);
				} else {
					grid.init(null, itemCount);
				}
				grid.init(item, itemCount);
			}

			return bag;
		} catch (IOException e) {
			e.printStackTrace();
		}

		return null;
	}

	public static byte[] getBagsDBBytes(Bags bags) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream(500);
		DataOutputStream dos = new DataOutputStream(baos);
		try {
			dos.write(1); // version
			dos.write(bags.getSize());
			for (int i = 0; i < bags.getSize(); i++) {
				Bag bag = bags.getBag(i);
				dos.write(bag.getId());
				dos.write(getBagDBBytes(bag));
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return baos.toByteArray();
	}

	public static byte[] getBagDBBytes(Bag bag) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream(500);
		DataOutputStream dos = new DataOutputStream(baos);
		int gridCount = bag.getSize();
		try {
			dos.writeShort(gridCount);
			for (int i = 0; i < gridCount; i++) {
				BagGrid bagGrid = bag.getGrid(i);
				int itemCount = bag.getGridItemCount(i);
				dos.writeShort(itemCount);
				if (itemCount > 0) {
					dos.write(getGameItemDBBytes(bagGrid.getItem()));
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

		return baos.toByteArray();
	}

	public static Equipments getEquipmentsFromDB(byte[] bytes, Playerinfo owner) {
		ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
		DataInputStream dis = new DataInputStream(bais);
		EquipmentsEx equs = new EquipmentsEx(owner);
		if (owner != null && owner instanceof Playerinfo) {
			owner.setEquipments(equs);
		}
		try {
			int version = dis.readByte(); // version;
			int count = dis.readByte();
			for (int i = 0; i < count; i++) {
				int c = dis.readByte();
				if (c == 1) {
					Equipment equ = (Equipment) getGameItemFromDB(dis);
					equs.equ(i, equ, null);
				}
			}

		} catch (IOException e) {
			e.printStackTrace();
		}
		return equs;
	}


	public static GameItem getGameItemFromDB(DataInputStream dis) {
		BaseItem item;
		try {
			int version = dis.read();
			if (1 == version) 
			{
				return getFromDB1(dis);
			} 
			else 
			{
				return null;
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (PersistenceException e) {
			e.printStackTrace();
		}
		return null;
	}

	private static GameItem getFromDB1(DataInputStream dis) throws IOException,
			PersistenceException {
		GameItem item;
		int itemInstanceId = dis.readInt();
		int itemId = dis.readInt();
		ItemTemplate template = Platform.getAppContext().get(ItemService.class)
				.getItemTemplate(itemId);
		if (template == null) {
			log.error("[ILLEGALITEM]ITEMID[" + itemId + "]");
			throw new IllegalArgumentException();
		}
		boolean bound = dis.read() == 0 ? false : true;
		
		//long id = dis.readLong();
		item = Platform.getAppContext().get(ItemService.class).createGameItem(template, itemInstanceId);
		item.setBound(bound);
		return item;
	}


	public static byte[] getGameItemDBBytes(GameItem item) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream(200);
		DataOutputStream dos = new DataOutputStream(baos);
		try 
		{
			dos.write(1);// version
			dos.writeInt(item.getInstanceId());
			dos.writeInt(item.getTemplate().getId());
			dos.write(item.isBound() ? 1 : 0);
		} 
		catch (IOException e) 
		{
			e.printStackTrace();
		}
		return baos.toByteArray();
	}

	public static byte[] getEquipmentsDBBytes(Equipments equs) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream(500);
		DataOutputStream dos = new DataOutputStream(baos);
		try {
			dos.write(1); // version
			dos.write(equs.getEquipmentCount());
			for (int i = 0; i < equs.getEquipmentCount(); i++) {
				GameItem item = equs.getEquipment(i);
				if (item == null) {
					dos.write(0);
				} else {
					dos.write(1);
					dos.write(getGameItemDBBytes(item));
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return baos.toByteArray();
	}

	public static Object getStoreHousesFromDB(byte[] bytes, Playerinfo owner) {
		ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
		DataInputStream dis = new DataInputStream(bais);
		Bags bags = null;
		try {
			int version = dis.readByte(); // version;
			int bagCount = dis.readByte();

			bags = new StoreHouses(owner, bagCount);
			for (int i = 0; i < bagCount; i++) {
				int id = dis.readByte();
				Bag bag = getStoreHouseFromDB(dis, bags, id);
				bags.addBag(bag);
			}

		} catch (IOException e) {
			e.printStackTrace();
		} 
		return bags;
	}
 
	public static Bag getStoreHouseFromDB(DataInputStream dis, Bags bags, int id) {
		Bag bag = null;
		try {
			int gridCount = dis.readShort();
			int addSize = gridCount - 15;
			bag = new StoreHouse(bags, id, 15, addSize > 0 ? addSize : 0);
			for (int i = 0; i < gridCount; i++) {
				int itemCount = dis.readShort();
				BagGrid grid = bag.getGrid(i);
				GameItem item = null;
				if (itemCount > 0) {
					item = getGameItemFromDB(dis);
				} else {
					grid.init(null, itemCount);
				}
				grid.init(item, itemCount);
			}

			return bag;
		} catch (IOException e) {
			e.printStackTrace();
		}

		return null;
	}
}
